﻿
using InfrastructureBase.Base.AuthBase.CustomAuth;
using InfrastructureBase.Base.AuthBase.JwtAuth;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InfrastructureBase.Base.AuthBase
{
    public static class AuthExtensions
    {
        /// <summary>
        /// jwt相关服务
        /// </summary>
        /// <param name="services"></param>
        public static IServiceCollection AddJwtAuthHelperService(this IServiceCollection services,IConfiguration configuration)
        {
            if (services == null)
                throw new ArgumentNullException(nameof(services));

            services.Configure<JwtConfig>(configuration);
            services.AddSingleton(new JwtHelper(services.BuildServiceProvider()));
            return services;
        }

        public static AuthenticationBuilder AddCustomJwtBearer(this AuthenticationBuilder builder, string authenticationScheme, Action<JwtBearerOptions> configureOptions)
        {
            return builder.AddJwtBearer(authenticationScheme,options =>
            {
                configureOptions(options);

                options.Events = new JwtBearerEvents
                {
                    OnMessageReceived = context =>
                    {
                        var accessToken = context.Request.Query["access_token"];
                        var path = context.HttpContext.Request.Path;
                        if (!string.IsNullOrEmpty(accessToken) &&
                            (path.StartsWithSegments("/hubs/messagehub")))
                        {
                            context.Token = accessToken;
                        }
                        return Task.CompletedTask;
                    },

                    //在Token验证通过后调用
                    OnAuthenticationFailed = context =>
                    {
                        var jwtHandler = new JwtSecurityTokenHandler();
                        var token = context.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
                        if (!string.IsNullOrEmpty(token) && jwtHandler.CanReadToken(token))
                        {
                            var jwtToken = jwtHandler.ReadJwtToken(token);

                            if (jwtToken.Issuer != options.TokenValidationParameters.ValidIssuer)
                                context.Response.Headers.Add("Token-Error-Iss", "issuer is wrong!");

                            if (jwtToken.Audiences.FirstOrDefault() != options.TokenValidationParameters.ValidAudience)
                                context.Response.Headers.Add("Token-Error-Aud", "Audience is wrong!");
                        }

                        if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                            context.Response.Headers.Add("Token-Expired", "true");
                        return Task.CompletedTask;
                    },

                    //未授权时调用失败
                    OnChallenge = context =>
                    {
                        if (context.Error != null)
                        {
                            string message = context.ErrorDescription;
                        }
                        context.Response.Headers.Add("Token-Error-Iss", "请授权");
                        return Task.CompletedTask;
                    },
                    //在Token验证通过后调用
                    //OnTokenValidated = context => { 
                    //}
                };
            });
        }

    }
}
